package com.huike.web.controller.system;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.huike.clues.service.ISysMenuService;
import com.huike.common.constant.Constants;
import com.huike.common.core.domain.AjaxResult;
import com.huike.common.core.domain.entity.SysMenu;
import com.huike.common.core.domain.entity.SysUser;
import com.huike.common.core.domain.model.LoginBody;
import com.huike.common.core.domain.model.LoginUser;
import com.huike.common.utils.ServletUtils;
import com.huike.framework.web.service.SysLoginService;
import com.huike.framework.web.service.SysPermissionService;
import com.huike.framework.web.service.TokenService;


/**
 *          第一种 就是  一个用户对应一个 secret （也就是 私钥，不能泄露 用于对 header 和 payload 进行加密 生成签名的 那个东西）
 *              大致 实现方式 ：用户在第一次登录的时候 会根据 用户 的账号（唯一）
 *             随机生成 一个uuid 作为私钥 （可以保存至redis中）形式：（K）账号：密钥(V)
 *             下次登录 取出用户的账号 获取到 他的 私钥， 然后进行 验签。（成功 就成功 ，失败就失败）。
 *             当用户想要 修改 密码时 ，会重新根据他的账号 生成 一个 secret 替换原有的 （这样 用户的密码和 密钥都可以 实现修改）
 *             以上就是  用户粒度的 密钥管理 （优点 是符合 jwt 这种无状态 初衷 缺点 需要额外的 内存 来维护 大量的密钥 ，
 *                 假如 用户 千万级别  那个这个内存占用 就非常 大了 ，当然也可能 出现其他问题 密钥的及时性要求高 。。。。。
 *              ）
 *
 *          第二种 修改密码  即修改 密钥 其实原理 跟第一种差不多 （也是账号 跟密码绑定 等同于 账号与私钥进行绑定 ）
 *
 *
 *
 *
 *
 */

/**
 * 登录验证
 * 
 * 
 */
@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private TokenService tokenService;

    /**
     * 登录方法
     * 
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {

        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());

        //登录成功后 响应用户一个token (证明用户是登录状态)
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 获取用户信息
     * 
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {

        //用户登录成功  获取用户的权限 和角色等信息 （前端应 是根据用户的角色与权限 来显示 对应的模块）
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());

        SysUser user = loginUser.getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    //@ApiOperation("获取路由信息")
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {

        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        // 用户信息
        SysUser user = loginUser.getUser();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}
